#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
#include <vector>

int massage(vector<int>& nums)
{
    int n = nums.size();
    if (n == 0)
        return 0;
    vector<int> f(n), g(n);
    f[0] = nums[0];

    for (int i = 1; i < n; i++)
    {
        f[i] = g[i - 1] + nums[i];
        g[i] = max(g[i - 1], f[i - 1]);
    }
    return max(f[n - 1], g[n - 1]);
}

//int rob(vector<int>& nums)
//{
//    int n = nums.size();
//    return max(nums[0] + rob1(nums, 2, n - 2), rob1(nums, 1, n - 1));
//}
//
//int rob1(vector<int>& nums, int begin, int end)
//{
//    if (begin > end)
//        return 0;
//    int n = nums.size();
//    vector<int> f(n), g(n);
//    f[begin] = nums[begin];
//
//    for (int i = begin + 1; i <= end; i++)
//    {
//        f[i] = nums[i] + g[i - 1];
//        g[i] = max(g[i - 1], f[i - 1]);
//    }
//    return max(f[end], g[end]);
//}

int deleteAndEarn(vector<int>& nums)
{
    int n = nums.size();
    int m = 0;
    for (int i = 0; i < n; i++)
    {
        if (nums[i] > m)
            m = nums[i];
    }

    vector<int> arr(m + 1);
    for (int i = 0; i < n; i++)
    {
        arr[nums[i]] += nums[i];
    }

    vector<int> f(m + 1), g(m + 1);
    f[0] = arr[0];
    for (int i = 1; i <= m; i++)
    {
        f[i] = arr[i] + g[i - 1];
        g[i] = max(f[i - 1], g[i - 1]);
    }
    return max(f[m], g[m]);
}

int minCost(vector<vector<int>>& nums)
{
    int n = nums.size();
    vector<vector<int>> red(n + 1, vector<int>(3));
    auto green = red;
    auto blue = red;

    for (int i = 1; i <= n; i++)
    {
        red[i][0] = nums[i - 1][0] + min(blue[i - 1][1], green[i - 1][2]);
        blue[i][1] = nums[i - 1][1] + min(red[i - 1][0], green[i - 1][2]);
        green[i][2] = nums[i - 1][2] + min(red[i - 1][0], blue[i - 1][1]);
    }
    return min(red[n][0], min(blue[n][1], green[n][2]));
}

//int maxProfit(vector<int>& prices)
//{
//    int n = prices.size();
//    vector<vector<int>> dp(n, vector<int>(3));
//    dp[0][0] = -prices[0];
//
//    for (int i = 1; i < n; i++)
//    {
//        dp[i][0] = max(dp[i - 1][0], dp[i - 1][2] - prices[i]);
//        dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
//        dp[i][2] = dp[i - 1][1];
//    }
//    return max(dp[n - 1][1], dp[n - 1][2]);
//}

//int maxProfit(vector<int>& prices, int fee)
//{
//    int n = prices.size();
//    vector<vector<int>> dp(n, vector<int>(2));
//    dp[0][0] = -prices[0];
//
//    for (int i = 1; i < n; i++)
//    {
//        dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
//        dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee);
//    }
//    return dp[n - 1][1];
//}

int maxProfit(vector<int>& prices)
{
    int n = prices.size();
    vector<vector<int>> f(n, vector<int>(3, -0x3f3f3f3f));
    auto g = f;
    f[0][0] = -prices[0];
    g[0][0] = 0;
    for (int i = 1; i < n; i++)
    {
        for (int j = 0; j <= 2; j++)
        {
            f[i][j] = max(f[i - 1][j], g[i - 1][j] - prices[i]);
            g[i][j] = g[i - 1][j];
            if (j - 1 >= 0)
                g[i][j] = max(g[i][j], f[i - 1][j - 1] + prices[i]);
        }
    }

    int ret = 0;
    for (int i = 0; i < 3; i++)
    {
        ret = max(ret, g[n - 1][i]);
    }
    return ret;
}

int maxProfit2(int k, vector<int>& prices)
{
    int n = prices.size();
    k = min(k, n / 2);

    vector<vector<int>> f(n, vector<int>(k + 1, -0x3f3f3f3f));
    auto g = f;
    f[0][0] = -prices[0];
    g[0][0] = 0;

    for (int i = 1; i < n; i++)
    {
        for (int j = 0; j <= k; j++)
        {
            f[i][j] = max(f[i - 1][j], g[i - 1][j] - prices[i]);
            g[i][j] = g[i - 1][j];
            if (j - 1 >= 0)
                g[i][j] = max(g[i][j], f[i - 1][j - 1] + prices[i]);
        }
    }

    int ret = 0;
    for (int i = 0; i <= k; i++)
    {
        ret = max(ret, g[n - 1][i]);
    }
    return ret;
}


void* mymemcpy(void* dest, void* src,int num)
{
    void* ret = dest;
    //int i = 0;
    //while ( i < num)
    //{
    //    *((char*)dest + i) = *((char*)src + i);
    //    i++;
    //}

    while (num--)
    {
        *(char*)dest = *(char*)src;
        dest = ((char*)dest)+ 1;
        src = ((char*)src) + 1;
    }
    return ret;
}

void* mymemmove(void* dest, void* src, int num)
{
    void* ret = dest;
    if (dest < src)
    {
        while (num--)
        {
            *(char*)dest = *(char*)src;
            dest = ((char*)dest) + 1;
            src = ((char*)src) + 1;
        }
    }
    else
    {
        while (num--)
        {
            *((char*)dest + num) = *((char*)src + num);
        }
    }
    return ret;
}

int main()
{
    int arr[5];
    int arr2[] = { 1,2,3,4,5 };
    mymemmove(arr2+3, arr2, sizeof(int) * 2);
    return 0;
}